library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

Library UNISIM;
use UNISIM.vcomponents.all;

entity OEM_Interface is
        Port(IMG0_I2C_Clk : out std_logic;
	         		IMG0_I2C_Data : out std_logic;
			       IMG0_Data : in std_logic_vector(9 downto 0);
			       IMG0_PIXEL_Clk : in std_logic;
			       IMG0_ROW_EN : in std_logic;
			       IMG0_VSYNC : in std_logic;
			       IMG0_RST : out std_logic;
			
			       IMG1_I2C_Clk : out std_logic;
			       IMG1_I2C_Data : out std_logic;
			       IMG1_Data : in std_logic_vector(9 downto 0);
			       IMG1_PIXEL_Clk : in std_logic;
			       IMG1_ROW_EN : in std_logic;
			       IMG1_VSYNC : in std_logic;
			       IMG1_RST : out std_logic;
			
			       OEM_I2C_Clk : in std_logic;
			       OEM_I2C_Data : inout std_logic;
			       OEM_Data : out std_logic_vector(9 downto 0);
			       OEM_PIXEL_Clk : out std_logic;
			       OEM_ROW_EN : out std_logic;
			       OEM_VSYNC : out std_logic;
			
			       Clk_100MHz : in std_logic;
			
	     				  SW : in std_logic_vector(3 downto 0);
	     				  LED : out std_logic_vector(3 downto 0)
             );
end OEM_Interface;

architecture beh of OEM_Interface is

  component I2Cslave_debug is
    Port ( Clk : in  STD_LOGIC;
           FPGAClk : in std_logic;
           rid_valid : out std_logic;
           register_id : out std_logic_vector(7 downto 0);
           Data_to_send : in std_logic_vector(15 downto 0);
           dout_valid : out std_logic; 
           Data_out : out std_logic_vector(15 downto 0);
           Direction : out std_logic;
           I2C_toBuffer : out std_logic;
           I2C_fromBuffer : in std_logic);
  end component;
  
  signal imgSel : std_logic:='0'; --imager selection signal
  signal current_row : std_logic; --current ROW_EN signal
  signal current_vsync : std_logic; --current VSYNC signal
  signal current_data : std_logic_vector(9 downto 0);  --current Data bus
  signal current_pclk : std_logic; --current PIXEL Clock signal
  signal oem_i2cClk,oem_outI2Cdata,oem_inI2Cdata : std_logic; --OEM I2C signals
  
  signal fpgaClk : std_logic; --onboard FPGA clock
  signal slave_regID_valid : std_logic; --I2C Register ID Data valid
  signal slave_regID : std_logic_vector(7 downto 0);  --I2C Register ID Data
  signal slave_dataToSend : std_logic_vector(15 downto 0);  --I2C reply data
  signal slave_dataOut_valid : std_logic; --I2C Data valid
  signal slave_dataOut : std_logic_vector(15 downto 0); --I2C Data
  signal slave_direction : std_logic; --I2C Direction (not sure what this is for...)
  signal sled : std_logic_vector(3 downto 0):="1111";
begin
  
  Slave: I2Cslave_debug port map(oem_i2cClk,fpgaClk,slave_regID_valid,slave_regID,slave_dataToSend,
                                 slave_dataOut_valid,slave_dataOut,slave_direction,oem_inI2Cdata,oem_outI2Cdata);

  --OEM Board data signals
  OEM_ROW_EN<=current_row;
	OEM_VSYNC<=current_vsync;
	OEM_Data<=current_data;
	OEM_PIXEL_Clk<=current_pclk;
	
	--I2C signals
	IMG0_I2C_Clk<='Z';
	IMG0_I2C_Data<='Z';
	IMG1_I2C_Clk<='Z';
	IMG1_I2C_Data<='Z';
	oem_i2cClk <= OEM_I2C_Clk;
	
	--Display LEDs
	LED<=sled;
	
	--Imager Reset signals (1=Normal, 0=Reset)
	IMG0_RST<='1';
	IMG1_RST<='1';
	
	--Input Clock
	fpgaClk<=Clk_100MHz;
	
	-----------------------------------
	--Imager switching process
	--Imager0 is selected when imgSel=0
	--Imager1 is selected when imgSel=1
	switch: process(imgSel)
	begin
		if imgSel = '1' then	--choose default camera
			current_data<=IMG0_Data;	--this is when 0
			current_row<=IMG0_ROW_EN;
			current_vsync<=IMG0_VSYNC;
			current_pclk<=IMG0_PIXEL_Clk;
		else
			current_data<=IMG1_Data;	--this is when 1
			current_row<=IMG1_ROW_EN;
			current_vsync<=IMG1_VSYNC;
			current_pclk<=IMG1_PIXEL_Clk;
		end if;
	end process;

  ---------------------------
  --I2C packet processing FSM
  i2c_proc: process(slave_regID_valid,slave_regID,slave_dataOut_valid,slave_dataOut)
  begin
    if slave_regID_valid='1' and slave_dataOut_valid='1' then
		sled<=sled+1;
      case slave_regID is
        when "10111100" =>
          imgSel<=slave_dataOut(0);
        when others=> null;
      end case;
    end if;
  end process;

  --------------------------
  --Slave Data signal buffer
  IOBUF_inst : IOBUF 
		generic map (
	  DRIVE => 12, 
			IBUF_DELAY_VALUE => "0", 	-- Specify the amount of added input delay for buffer, "0"-"16" (Spartan-3E only)
			IFD_DELAY_VALUE => "AUTO", -- Specify the amount of added delay for input register, "AUTO", "0"-"8" (Spartan-3E only)
			IOSTANDARD => "DEFAULT",
			SLEW => "SLOW") 
		port map (
			O => oem_outI2Cdata, 		-- Buffer output
			IO => OEM_I2C_Data, 	-- Buffer inout port (connect directly to top-level port)
	   	I => oem_inI2Cdata, 		-- Buffer input
			T => slave_direction		-- 3-state enable input
		); 
end beh;